/*
 * ResourceEditorUI.java
 *
 * Created on November 24, 2008, 7:30 PM
 */

package deadlocksim.gui;

import java.io.IOException;
import java.util.*;
import deadlocksim.*;
import deadlocksim.backend.*;
import deadlocksim.backend.process.*;
import deadlocksim.backend.resources.*;
import deadlocksim.backend.resources.ResourceManager.*;
import deadlocksim.backend.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import java.io.*;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 *
 * @author  KarenPell
 */
public class ResourceEditorUI extends javax.swing.JFrame //implements ActionListener {
{    
    private final static String newline = "\n";    
    private String filename = null;
    private MainPage mainPage;
    private DeadlockSim mySim;    

    /** Creates new form ResourceEditorUI */
    public ResourceEditorUI(MainPage main) {
        mainPage = main;
        initComponents();
        this.mySim = mainPage.getDeadlockSim();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jTextFieldNew = new javax.swing.JTextField();
        jComboResourceList = new javax.swing.JComboBox();
        JTextFieldQuantity = new javax.swing.JTextField();
        jButtonNewType = new javax.swing.JButton();
        jButtonAdd = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextAreaResources = new javax.swing.JTextArea();
        jLabel1 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jButtonRemove = new javax.swing.JButton();
        jButtonSave = new javax.swing.JButton();
        jButtonOpen = new javax.swing.JButton();
        jButtonCancel = new javax.swing.JButton();
        jButtonLoad = new javax.swing.JButton();

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Resource Editor"));

        jTextFieldNew.setToolTipText("Enter a name for the resource.");

        jComboResourceList.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "{Select a resource type}", "Hard Disk (ID 0)", "CD-ROM (ID 1)", "Printer (ID 2)" }));
        jComboResourceList.setToolTipText("Select the resource to define.");
        jComboResourceList.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jComboResourceListActionPerformed(evt);
            }
        });

        JTextFieldQuantity.setText("1");
        JTextFieldQuantity.setToolTipText("Add the number of resources to be defined.");
        JTextFieldQuantity.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                JTextFieldQuantityActionPerformed(evt);
            }
        });

        jButtonNewType.setText("Create Resource Type");
        jButtonNewType.setToolTipText("Select this button to add the new resource type.");
        jButtonNewType.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonNewTypeActionPerformed(evt);
            }
        });

        jButtonAdd.setText("Add Resource(s) to Listing ->");
        jButtonAdd.setToolTipText("Select this button to add the resource and it's quantity to the resource file.");
        jButtonAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAddActionPerformed(evt);
            }
        });

        jTextAreaResources.setColumns(20);
        jTextAreaResources.setRows(5);
        jScrollPane1.setViewportView(jTextAreaResources);

        jLabel1.setText("Create a resource type named:");

        jLabel3.setText("Number to add:");

        jButtonRemove.setText("Remove Selected Entry");
        jButtonRemove.setToolTipText("Select one or more resources to remove and then select this button.");
        jButtonRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonRemoveActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel1)
                            .addComponent(jComboResourceList, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel3)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(JTextFieldQuantity, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(jTextFieldNew)))
                    .addComponent(jButtonAdd, javax.swing.GroupLayout.DEFAULT_SIZE, 264, Short.MAX_VALUE)
                    .addComponent(jButtonNewType, javax.swing.GroupLayout.DEFAULT_SIZE, 264, Short.MAX_VALUE))
                .addGap(28, 28, 28)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 268, Short.MAX_VALUE)
                    .addComponent(jButtonRemove, javax.swing.GroupLayout.DEFAULT_SIZE, 268, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(23, 23, 23)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(JTextFieldQuantity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jComboResourceList, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel3))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonAdd)
                        .addGap(48, 48, 48)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel1)
                            .addComponent(jTextFieldNew, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonNewType))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonRemove)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jButtonSave.setText("Save to File");
        jButtonSave.setToolTipText("Select this button to save the resource listing.");
        jButtonSave.setEnabled(false);
        jButtonSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSaveActionPerformed(evt);
            }
        });

        jButtonOpen.setText("Open Resource File");
        jButtonOpen.setToolTipText("Select this button to open an existing resource listing.");
        jButtonOpen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonOpenActionPerformed(evt);
            }
        });

        jButtonCancel.setText("Exit Editor");
        jButtonCancel.setToolTipText("Select this button to Cancel the changes and close the form.");
        jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCancelActionPerformed(evt);
            }
        });

        jButtonLoad.setText("Load Resources into Sim");
        jButtonLoad.setToolTipText("Select this button to load the resources into the simulator.");
        jButtonLoad.setEnabled(false);
        jButtonLoad.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonLoadActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jButtonOpen)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonSave)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 120, Short.MAX_VALUE)
                        .addComponent(jButtonLoad)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonCancel)
                        .addGap(18, 18, 18))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonCancel)
                    .addComponent(jButtonLoad)
                    .addComponent(jButtonOpen)
                    .addComponent(jButtonSave))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void jButtonNewTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonNewTypeActionPerformed
// If the user selects this button, creates a new Resource type.
    if (jTextFieldNew.getText().isEmpty()) {
        JOptionPane.showMessageDialog(this, "Enter the name of the resource type.");
    } 
    else {
        Integer iListCount = jComboResourceList.getItemCount();
        jComboResourceList.addItem(this.jTextFieldNew.getText() + " (ID " + (iListCount-1) + ")");
        jTextFieldNew.setText("");
    }
        
}//GEN-LAST:event_jButtonNewTypeActionPerformed

private void jButtonAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAddActionPerformed
// Add the number of resources to the text area that will be saved as a resource list.
    Integer quantityFieldInt;
    String quantityFieldText = this.JTextFieldQuantity.getText();
    if (JTextFieldQuantity.getText().isEmpty()) {
        JOptionPane.showMessageDialog(this, "Enter the number of the selected resource to add.");
    }
    else {
        try
        {
            quantityFieldInt = new Integer(quantityFieldText);
        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(this, "You must specify numbers only in the Quantity field!");
            JTextFieldQuantity.setText("1");
            return;
        }
        Integer resourceIndex = jComboResourceList.getSelectedIndex() - 1;
        if (resourceIndex >= 0)
        {    
            jTextAreaResources.append(resourceIndex + " " + JTextFieldQuantity.getText() + newline);
            this.jButtonLoad.setEnabled(true);
            this.jButtonSave.setEnabled(true);
            JTextFieldQuantity.setText("1");
            // jComboResourceList.removeItem(jComboResourceList.getSelectedItem());
        }
        else
        {
            JOptionPane.showMessageDialog(this, "Please select a resource type.");
        }
    }
}//GEN-LAST:event_jButtonAddActionPerformed

private void jButtonSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSaveActionPerformed
// save the resource listing as a file
    if(jTextAreaResources.getText() == null || jTextAreaResources.getText().equals(""))
        return;
    File theFile = saveAs(null);
    if(filename != null)
        filename = theFile.getAbsolutePath();    
    jButtonLoad.setEnabled(true);
}//GEN-LAST:event_jButtonSaveActionPerformed

private void jButtonOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOpenActionPerformed
// Open the file 
    this.jTextAreaResources.setText("");
    File theFile = openFile();    
    filename = theFile.getAbsolutePath(); 
    jButtonLoad.setEnabled(true);
}//GEN-LAST:event_jButtonOpenActionPerformed

private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
    this.setVisible(false);
}//GEN-LAST:event_jButtonCancelActionPerformed

private void jButtonRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRemoveActionPerformed
    if(jTextAreaResources.getSelectedText() != null)
        this.jTextAreaResources.replaceSelection("");
    // Remove excess whitespace between and after entries
    String leftOverText = jTextAreaResources.getText().trim();
    String[] lines = leftOverText.split(newline);
    leftOverText = "";
    for(int i = 0; i < lines.length; i++)
    {
        if(! (lines[i].trim()).equals(""))
            leftOverText += lines[i]+newline;
    }
    jTextAreaResources.setText(leftOverText);
    
}//GEN-LAST:event_jButtonRemoveActionPerformed

private void jButtonLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonLoadActionPerformed
    if(jTextAreaResources.getText() == null || jTextAreaResources.getText().equals(""))
        return;
    
    if(filename == null)
    {
        filename = "resources.temp.txt";
        saveAs(filename);
        // Supply a temporary file
        //JOptionPane.showMessageDialog(this, "Please open a file or create and save a file before selecting Load.");
        //return;
    }
    ResourceFileLoader rLoader = new ResourceFileLoader(filename);
    try 
    {
        //DeadlockSim mySim = rLoader.createResources();        
        rLoader.createResources(mySim);
        this.jButtonLoad.setEnabled(false);
        this.jButtonSave.setEnabled(false);
        mainPage.pack();
        
        mySim.refreshDisplay();
        jTextAreaResources.setText("");
        filename = null;
        //DeadlockResourceDisplay display = mySim.getResourceDisplay();
        //display.rebuildDisplay();
        //mySim.refreshDisplay();
        //mySim.getResourceDisplay();
    } catch (IOException ex) 
    {
        System.err.println("Exception in resource load button.");
        Logger.getLogger(ResourceEditorUI.class.getName()).log(Level.SEVERE, null, ex);
        JOptionPane.showMessageDialog(this, "exception in load button.");
    }    

}//GEN-LAST:event_jButtonLoadActionPerformed

private void jComboResourceListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboResourceListActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_jComboResourceListActionPerformed

private void JTextFieldQuantityActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_JTextFieldQuantityActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_JTextFieldQuantityActionPerformed

    public File saveAs(String optionalFileName) 
    {
        File theFile = null;
        JFileChooser fc = null;
        int option = 0;
        
        
        
        if(optionalFileName == null)
        {
            fc = new JFileChooser(".");
            option = fc.showSaveDialog(this);
            theFile = fc.getSelectedFile();
        }
        else
        {
            theFile = new File(optionalFileName);
        
            try
            {
                if(theFile.exists())
                {
                    theFile.delete();
                    theFile.createNewFile();
                }
                else
                    theFile.createNewFile();
            }
            catch(Exception e)
            {
                mySim.sendMessage("Could not write resources file: " + e.getMessage(), true);
            }
            
            if(! theFile.exists())
            {
                fc = new JFileChooser(".");
                option = fc.showSaveDialog(this);
                theFile = fc.getSelectedFile();
            }
        }
        
        // jason. karen changed to return a file
        
        
        if (( fc != null && JFileChooser.APPROVE_OPTION == option)
                || (fc == null && theFile.exists()))
        {
            
            try 
            {
                BufferedWriter out = new BufferedWriter(new FileWriter(theFile));
                String contents = jTextAreaResources.getText();
                String[] lines = contents.split(newline);
                for(int i = 0; i < lines.length; i++)
                {
                    out.write(lines[i]);
                    out.newLine();
                }
                out.close();
                System.out.println(contents);
            } 
            catch (IOException e) 
            {
                System.err.println("Can't write file: " + e.getMessage() + "\n" + e.getStackTrace());
                return null;
            }
            return theFile;

        }
        else
        {
            System.err.println("Nothing to write");
            int i = 0;
        }
        return null;
       
    }

    public File openFile() {
        // open the selected file and put the contents in the process listing
        JFileChooser fc = new JFileChooser(".");
        int option = fc.showOpenDialog(this);
        File theFile = fc.getSelectedFile();
        int i=0;
        //FileNameExtensionFilter filter = new FileNameExtensionFilter(
        //"Text Documents", "txt");
        //fc.setFileFilter(filter);
        try
        {
            BufferedReader in = new BufferedReader(new FileReader(theFile));
            // used sample from http://www.wellho.net/mouth/1239_End-of-File-on-a-Java-BufferedReader.html
            while (true){
                if (! in.ready()) break;
                    String next_line = in.readLine();
                    this.jTextAreaResources.append(next_line + newline);
                    i++;
            }
        }
        catch (IOException e)
        {
                System.err.println("Can't read file: " + e.getMessage() + "\n" + e.getStackTrace());
                return null;            
        }
        return theFile;
    }

    /**
    * @param args the command line arguments
    */
    /*
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ResourceEditorUI().setVisible(true);
            }
        });
    }
    */
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField JTextFieldQuantity;
    private javax.swing.JButton jButtonAdd;
    private javax.swing.JButton jButtonCancel;
    private javax.swing.JButton jButtonLoad;
    private javax.swing.JButton jButtonNewType;
    private javax.swing.JButton jButtonOpen;
    private javax.swing.JButton jButtonRemove;
    private javax.swing.JButton jButtonSave;
    private javax.swing.JComboBox jComboResourceList;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextAreaResources;
    private javax.swing.JTextField jTextFieldNew;
    // End of variables declaration//GEN-END:variables
/*
    public void actionPerformed(ActionEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
*/
}
